package com.zkthink.ceres.finance.service.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zkthink.base.R;
import com.zkthink.base.service.SuperServiceImpl;
import com.zkthink.cache.repository.CacheRepository;
import com.zkthink.ceres.common.constant.CacheKey;
import com.zkthink.ceres.finance.dao.MemberCollectingAccountMapper;
import com.zkthink.ceres.finance.dto.BankDTO;
import com.zkthink.ceres.finance.dto.MemberCollectingAccountSaveDTO;
import com.zkthink.ceres.finance.dto.MemberCollectingAccountUpdateDTO;
import com.zkthink.ceres.finance.entity.MemberCollectingAccount;
import com.zkthink.ceres.finance.service.MemberCollectingAccountService;
import com.zkthink.ceres.finance.util.CardUtil;
import com.zkthink.ceres.sms.dto.VerificationCodeDTO;
import com.zkthink.ceres.sms.enumeration.VerificationCodeType;
import com.zkthink.database.mybatis.conditions.Wraps;
import com.zkthink.dozer.DozerUtils;
import com.zkthink.exception.BizException;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 业务实现类
 * 收款帐户表
 * </p>
 *
 * @author vivi.huang
 * @date 2020-05-25
 */
@Slf4j
@Service
@AllArgsConstructor
public class MemberCollectingAccountServiceImpl extends SuperServiceImpl<MemberCollectingAccountMapper, MemberCollectingAccount> implements MemberCollectingAccountService {

    private DozerUtils dozerUtils;
    private CacheRepository cacheRepository;

    @Autowired
    private MemberCollectingAccountMapper memberCollectingAccountMapper;

    @Override
    public R<Boolean> bindingMemberAccount(MemberCollectingAccountSaveDTO collectingAccountSaveDTO) {
        if (!this.checkVerification(collectingAccountSaveDTO.getPhone(), collectingAccountSaveDTO.getType(), collectingAccountSaveDTO.getCode())) {
            throw new BizException("验证码验证失败");
        }

        if (!validateBankCard(collectingAccountSaveDTO)) {
            throw new BizException("银行卡号验证不通过");
        }
        MemberCollectingAccount memberCollectingAccount = memberCollectingAccountMapper.selectByMid(collectingAccountSaveDTO.getMid());
        if (memberCollectingAccount != null) {
            return R.fail("已有绑定卡片");
        }
        MemberCollectingAccount collectingAccount = dozerUtils.map(collectingAccountSaveDTO, MemberCollectingAccount.class);
        return R.success(this.save(collectingAccount));
    }

    @Override
    public R<Boolean> changeMemberAccount(MemberCollectingAccountUpdateDTO collectingAccountUpdateDTO) {
        if (!this.checkVerification(collectingAccountUpdateDTO.getPhone(), collectingAccountUpdateDTO.getType(), collectingAccountUpdateDTO.getCode())) {
            throw new BizException("验证码验证失败");
        }

        if (!checkOldCardInfo(collectingAccountUpdateDTO)) {
            throw new BizException("原卡信息不正确");
        }
        MemberCollectingAccount collectingAccount = dozerUtils.map(collectingAccountUpdateDTO, MemberCollectingAccount.class);
        return R.success(this.updateAllById(collectingAccount));
    }

    @Override
    public R<Boolean> cancelBindingMemberAccount(VerificationCodeDTO verificationCodeDTO) {
        if (!this.checkVerification(verificationCodeDTO.getMobile(), verificationCodeDTO.getType(), verificationCodeDTO.getCode())) {
            throw new BizException("验证码验证失败");
        }
        return R.success(this.remove(Wraps.lbQ()));
    }

    @Override
    public R<List<BankDTO>> findBankList() {
        return R.success(CardUtil.BANK_MAP.entrySet().stream().map(e -> new BankDTO(e.getKey(), e.getValue())).collect(Collectors.toList()));
    }

    @Override
    public R<MemberCollectingAccount> selectByMid(Long mid) {
        return R.success(memberCollectingAccountMapper.selectByMid(mid));
    }

    private boolean checkVerification(String mobile, VerificationCodeType type, String code) {
        String key = CacheKey.buildTenantKey(CacheKey.REGISTER_COLLECTING_ACCOUNT, type.name(), mobile);
        String cacheCode = cacheRepository.get(key);
        return code.equals(cacheCode);
    }

    private boolean validateBankCard(MemberCollectingAccountSaveDTO dto) {
        try {
            OkHttpClient client = new OkHttpClient();
            Request request = new Request.Builder().url(buildAliUrl(dto.getCardNumber())).build();
            Response response = client.newCall(request).execute();
            String value = response.body().string();
            JSONObject json = JSON.parseObject(value);
            return CardUtil.check(dto.getBank(), json.getString("bank"));
        } catch (Exception e) {
            log.error("验证银行卡接口异常", e);
            throw new BizException(e.toString());
        }

    }

    private boolean checkOldCardInfo(MemberCollectingAccountUpdateDTO collectingAccountUpdateDTO) {
        MemberCollectingAccount collectingAccount = this.getById(collectingAccountUpdateDTO.getId());
        return collectingAccount.getCardNumber().equals(collectingAccountUpdateDTO.getOldCardNumber())
                && collectingAccount.getCardholderName().equals(collectingAccountUpdateDTO.getOldCardHolderName());
    }

    private String buildAliUrl(String cardNumber) {
        return CardUtil.getCheckUrl(cardNumber);
    }
}
